﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LabMonitorRemote
{
    public partial class frmManageLoggers : Form
    {
        List<DewkLogger> _LoggerList = new List<DewkLogger>();

        private Boolean _InsertNewRecord;
        private Int32 _RecordDatabaseKey;
        private readonly List<Int32> _RecIntervals = new List<Int32>(){1,2,5,10,15,30,60,120,300,600,900,1200,1800,3600};
        private readonly List<Int32> _PacketSizes = new List<Int32>() {128,256,512,1024,2048};

        public frmManageLoggers()
        {
            InitializeComponent();
        }

        private void frmManageLoggers_Load(object sender, EventArgs e)
        {
            foreach (Int32 interval in _RecIntervals)
                cboRecordingInterval.Items.Add(interval);
            foreach (Int32 size in _PacketSizes)
                cboPacketSize.Items.Add(size);
            cboPacketSize.SelectedIndex = _PacketSizes.IndexOf(Properties.Settings.Default.DownloadPacketSize);
            grpLoggerInfo.Enabled = false;
            grpChannelSettings.Enabled = false;
            btnEditSelectedLogger.Enabled = false;
            ReLoadDailyDownloadSettings();
            ReLoadLoggers();
            
            // THESE ELEMENTS ARE MADE INVISIBLE UNTIL THEIR FUNCTIONALITY IS ESTABLISHED
            lblPassword.Visible = false;
            txtPassword.Enabled = false;
            txtPassword.Visible = false;

        }

        private void ReLoadLoggers()
        {

            _LoggerList.Clear();

            using (var db = new LMRDataContext())
            {
                var loggers = from range in db.GetTable<SavedLogger>()
                              select range; //db.SavedLoggers.Take(9);

                foreach (var l in loggers)
                {
                    _LoggerList.Add(new DewkLogger(
                        l.LoggerName,
                        l.LoggerDescription,
                        l.LoggerIpAddress,
                        (Boolean)l.DisplayF,
                        (Int32)l.RecInterval,
                        (DateTime)l.LastDownloadedThrough,
                        (Boolean)l.Ch1Enabled,
                        (double)l.Ch1TempHigh,
                        (double)l.Ch1TempLow,
                        (double)l.Ch1HumidHigh,
                        (double)l.Ch1HumidLow,
                        (Boolean)l.Ch2Enabled,
                        (double)l.Ch2TempHigh,
                        (double)l.Ch2TempLow,
                        (double)l.Ch2HumidHigh,
                        (double)l.Ch2HumidLow,
                        (Int32)l.ID));
                }

                lstLoggers.Items.Clear();
                foreach (DewkLogger dewk in _LoggerList)
                    lstLoggers.Items.Add(dewk.LoggerName);
            }
        }

        private void btnTestComm_Click(object sender, EventArgs e)
        {
            MessageBox.Show(txtIPAddress.Text);
        }

        private void chkChannel1Enable_CheckedChanged(object sender, EventArgs e)
        {
            Ch1EnableDisable();
        }

        private void Ch1EnableDisable()
        {         
            if (chkChannel1Enable.Checked == true)
            {
                txtHumidHigh1.Enabled = true;
                txtHumidLow1.Enabled = true;
                txtTempHigh1.Enabled = true;
                txtTempLow1.Enabled = true;
            }
            else
            {
                txtHumidHigh1.Enabled = false;
                txtHumidLow1.Enabled = false;
                txtTempHigh1.Enabled = false;
                txtTempLow1.Enabled = false;
            }
                    
        }

        private void chkChannel2Enable_CheckedChanged(object sender, EventArgs e)
        {
            Ch2EnableDisable();
        }
        private void Ch2EnableDisable()
        {
            if (chkChannel2Enable.Checked == true)
            {
                txtHumidHigh2.Enabled = true;
                txtHumidLow2.Enabled = true;
                txtTempHigh2.Enabled = true;
                txtTempLow2.Enabled = true;
            }
            else
            {
                txtHumidHigh2.Enabled = false;
                txtHumidLow2.Enabled = false;
                txtTempHigh2.Enabled = false;
                txtTempLow2.Enabled = false;
            }
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void lstLoggers_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            // Pass selected index to method
            Int32 selectedIndex = lstLoggers.SelectedIndex;
            if (selectedIndex != -1)
            {
                LoadLoggerByIndex(selectedIndex);
                SetTemperatureLabels();
                btnEditSelectedLogger.Enabled = true;
            }
            else
            {
                btnEditSelectedLogger.Enabled = false;
            }
        }

        private void LoadLoggerByIndex(Int32 selectedIndex)
        {   // Load Selected Logger Info
            txtLoggerName.Text = _LoggerList[selectedIndex].LoggerName;
            txtDescripion.Text = _LoggerList[selectedIndex].LoggerDescription;
            txtIPAddress.Text = _LoggerList[selectedIndex].IpAddress;
            chkDisplayF.Checked = _LoggerList[selectedIndex].DisplayF;
            cboRecordingInterval.SelectedIndex = RecIntervalToIndex(_LoggerList[selectedIndex].RecordingInterval);
            cboRecordingInterval.SelectedValue = RecIntervalToIndex(_LoggerList[selectedIndex].RecordingInterval);
            txtLastDownloadedThrough.Text = _LoggerList[selectedIndex].LastDownloadedThrough.ToString();

            //Channel 1
            chkChannel1Enable.Checked = _LoggerList[selectedIndex].Ch1Enabled;
            txtTempHigh1.Text = _LoggerList[selectedIndex].Ch1TempHigh.ToString();
            txtTempLow1.Text = _LoggerList[selectedIndex].Ch1TempLow.ToString();
            txtHumidHigh1.Text = _LoggerList[selectedIndex].Ch1HumidHigh.ToString();
            txtHumidLow1.Text = _LoggerList[selectedIndex].Ch1HumidLow.ToString();

            //Channel 2
            chkChannel2Enable.Checked = _LoggerList[selectedIndex].Ch2Enabled;
            txtTempHigh2.Text = _LoggerList[selectedIndex].Ch2TempHigh.ToString();
            txtTempLow2.Text = _LoggerList[selectedIndex].Ch2TempLow.ToString();
            txtHumidHigh2.Text = _LoggerList[selectedIndex].Ch2HumidHigh.ToString();
            txtHumidLow2.Text = _LoggerList[selectedIndex].Ch2HumidLow.ToString();   
        }

        private Int32 RecIntervalToIndex(Int32 interval)
        {
            return _RecIntervals.IndexOf(interval);
        }
        private Int32 IndexToRecInterval(Int32 index)
        {
            return _RecIntervals[index];
        }


        private void btnEditSelectedLogger_Click(object sender, EventArgs e)
        {
            // Enable Fields on right
            _RecordDatabaseKey = _LoggerList[lstLoggers.SelectedIndex].DatabaseKeyValue;
            lstLoggers.Enabled = false;
            grpLoggerInfo.Enabled = true;
            grpChannelSettings.Enabled = true;
            Ch1EnableDisable();
            Ch2EnableDisable();
            txtPassword.Enabled = false;
            btnEditSelectedLogger.Enabled = false;
            btnNew.Enabled = false;
            btnDeleteLogger.Enabled = true;
        }

        private void bntNew_Click(object sender, EventArgs e)
        {
            // Clear Fields
            ClearAllFields();
            
            // _InsertNewRecord set to true
            _InsertNewRecord = true;
            
            // _RecordDatabaseKey set to null
            _RecordDatabaseKey = -1; /// reexamine this later ...
            
            // Disable selection List
            lstLoggers.Enabled = false;
            
            //Enable Sections
            grpLoggerInfo.Enabled = true;
            grpChannelSettings.Enabled = true;

            txtPassword.Enabled = false;
            btnEditSelectedLogger.Enabled = false;
            btnNew.Enabled = false;
            btnDeleteLogger.Enabled = false;
        }

        private void ClearAllFields()
        {
            txtLoggerName.Text = "";
            txtDescripion.Text = "";
            txtIPAddress.Text = "";
            chkDisplayF.Checked = true;
            cboRecordingInterval.SelectedIndex = RecIntervalToIndex(300);
            cboRecordingInterval.SelectedValue = 300;
            txtLastDownloadedThrough.Text = "";

            //Channel 1
            chkChannel1Enable.Checked = false;
            txtTempHigh1.Text = "";
            txtTempLow1.Text = "";
            txtHumidHigh1.Text = "";
            txtHumidLow1.Text = "";
            txtHumidHigh1.Enabled = false;
            txtHumidLow1.Enabled = false;
            txtTempHigh1.Enabled = false;
            txtTempLow1.Enabled = false;

            //Channel 2
            chkChannel2Enable.Checked = false;
            txtTempHigh2.Text = "";
            txtTempLow2.Text = "";
            txtHumidHigh2.Text = "";
            txtHumidLow2.Text = "";
            txtHumidHigh2.Enabled = false;
            txtHumidLow2.Enabled = false;
            txtTempHigh2.Enabled = false;
            txtTempLow2.Enabled = false;
        }


        private void btnCancel_Click(object sender, EventArgs e)
        {
            SetFormToOnLoad();
        }

        private void SetFormToOnLoad()
        {
            // clear input fields
            ClearAllFields();
            // _InsertNewRecord set to false
            _InsertNewRecord = false;
            _RecordDatabaseKey = 0;

            // Disable fields on right
            grpLoggerInfo.Enabled = false;
            grpChannelSettings.Enabled = false;

            // clear selected item
            lstLoggers.ClearSelected();
            lstLoggers.Enabled = true;
            btnNew.Enabled = true;
        }



        private void bntSave_Click(object sender, EventArgs e)
        {


            // Validate that Name is filled in
            if (txtLoggerName.Text == "")
            {
                string errorMessage = "You must enter a name for this logger.\nThe name will be used to quickly identify the device on the main screen.";
                MessageBox.Show(errorMessage, "No Name Entered");
            }
            // validate the IP address
            else if (!LMRStaticUtilities.ValidIPAddress(txtIPAddress.Text))
            {
                string errorMessage = 
                    "Please enter a valid IP Address\nThe IP Address is required for communication.\n\nThe IP Address of this logger can be found by going to:\nMenu -> Settings -> Comm Settings, and selecting LAN.\n\n NOTE: Ensure DHCP is OFF.";
                MessageBox.Show(errorMessage, "Invalid IPv4 Address");
            }
            // Create a DewkLogger based off the info on the form
            else
            {
                DewkLogger Dewk = new DewkLogger(
                    txtLoggerName.Text,
                    txtDescripion.Text,
                    txtIPAddress.Text,
                    chkDisplayF.Checked,
                    System.Convert.ToInt32(_RecIntervals[cboRecordingInterval.SelectedIndex]), // if -1 manage ...
                    new DateTime(1990, 1, 1, 0, 0, 0),

                    chkChannel1Enable.Checked,
                    SetDoubleValueFromTextBox(txtTempHigh1),
                    SetDoubleValueFromTextBox(txtTempLow1),
                    SetDoubleValueFromTextBox(txtHumidHigh1),
                    SetDoubleValueFromTextBox(txtHumidLow1),

                    chkChannel2Enable.Checked,
                    SetDoubleValueFromTextBox(txtTempHigh2),
                    SetDoubleValueFromTextBox(txtTempLow2),
                    SetDoubleValueFromTextBox(txtHumidHigh2),
                    SetDoubleValueFromTextBox(txtHumidLow2)
                    );

                // If chkEnableSettingsPush is checked
                if (chkEnableSettingsPush.Checked == true)
                {
                    // SHOW CONFIRM DIALOG 
                    string confirmMessage = "You checked Enable Push Settings." + Environment.NewLine + "Are you sure you want to push this configuration to the Logger?";
                    if (MessageBox.Show(confirmMessage, "Confirm Settings Push", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        // Validate password    
                        DewkSettingsConfiguration ThisConfiguration = new DewkSettingsConfiguration(Dewk);
                        ThisConfiguration.SetConfiguration();
                    }
                    // Push Settings to Dewk FIRST
                    // Save Settings to Databse
                    if (_InsertNewRecord)
                    {
                        InsertNewLogger(Dewk);
                    }
                    else
                    {
                        UpdateLogger(Dewk);
                    }
                }
                else
                {
                    string confirmMessage = "Save this logger?" + Environment.NewLine + "(Settings will not be pushed)";
                    if (MessageBox.Show(confirmMessage, "Confirm Save", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        if (_InsertNewRecord)
                        {
                            InsertNewLogger(Dewk);
                        }
                        else
                        {
                            UpdateLogger(Dewk);
                        }
                    }
                    //MessageBox.Show("ok");
                    // SHOW CONFIRM DIALOG
                    // Save Settings to Database only
                }

                // Show Confirm Save Dialog that displayes settings to be saved



                // push current time

                // Push Settings that are enabled

                // If channel is enabled, emable temp & humidity logging Otherwise disable ...


                // Get Settings from Logger
                // Insert New Record based on settings pulled from logger
                // Indicate success / fail
                // disable fields on right
                // Reload LoggerList

                // Otherwise State that it must be checked to save
            }
        }
        private double SetDoubleValueFromTextBox(TextBox TxtBox)
        {
            if (TxtBox.Text == "")
            {
                return 0;
            }
            else
            {
                return System.Convert.ToDouble(TxtBox.Text);
            }
        }

        private void GetSettingsFromLogger()
        {

        }

        private void PushSettingsToLogger()
        {

        }

        private void SaveLoggerToDatabase()
        {

        }


        private void btnChangePassword_Click(object sender, EventArgs e)
        {
            // if password is valid 
            // load form to enter new password  
            // require double confirmation to save 

        }

        private void chkEnableSettingsPush_CheckedChanged(object sender, EventArgs e)
        {
            if (chkEnableSettingsPush.Checked == true)
                txtPassword.Enabled = true;
            else
                txtPassword.Enabled = false;
            }

        private void btnDeleteLogger_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to delete this Logger?", "Confirm Delete", MessageBoxButtons.YesNo) == DialogResult.Yes && _RecordDatabaseKey != 0)
            {
                using (var db = new LMRDataContext())
                {
                    var deleteLoggers =
                        from logger in db.SavedLoggers
                        where logger.ID == this._RecordDatabaseKey
                        select logger;
                    foreach (var logger in deleteLoggers)
                    {
                        db.SavedLoggers.DeleteOnSubmit(logger);
                    }
                    try
                    {
                        db.SubmitChanges();
                        MessageBox.Show("Logger has been deleted.\nAny data stored from this logger will remain.", "Logger Deleted");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Error Deleting Record!");
                        Console.WriteLine(e);
                    }
                   
                    SetFormToOnLoad();
                    ReLoadLoggers();
                }
            }
        }

        private void InsertNewLogger(DewkLogger Dewk)
        {
            if (Dewk.LastDownloadedThrough == null)
            {   // Database should also force default value of 1900-01-01 00:00:00.000
                Dewk.LastDownloadedThrough = new DateTime(1900, 01, 01, 00, 00, 00);
            }

            using (var db = new LMRDataContext())
            {
                var addLogger =new SavedLogger(){

                    LoggerName = Dewk.LoggerName,
                    LoggerIpAddress = Dewk.IpAddress,
                    LoggerDescription = Dewk.LoggerDescription,
                    
                    DisplayF = Dewk.DisplayF,
                    LastDownloadedThrough = Dewk.LastDownloadedThrough,
                    RecInterval = Dewk.RecordingInterval,
                    
                    Ch1Enabled = Dewk.Ch1Enabled,
                    Ch2Enabled = Dewk.Ch2Enabled,
                    
                    Ch1TempHigh = System.Convert.ToDecimal(Dewk.Ch1TempHigh),
                    Ch1TempLow = System.Convert.ToDecimal(Dewk.Ch1TempLow),
                    Ch1HumidHigh = System.Convert.ToDecimal(Dewk.Ch1HumidHigh),
                    Ch1HumidLow = System.Convert.ToDecimal(Dewk.Ch1HumidLow),

                    Ch2TempHigh = System.Convert.ToDecimal(Dewk.Ch2TempHigh),
                    Ch2TempLow = System.Convert.ToDecimal(Dewk.Ch2TempLow),
                    Ch2HumidHigh = System.Convert.ToDecimal(Dewk.Ch2HumidHigh),
                    Ch2HumidLow = System.Convert.ToDecimal(Dewk.Ch2HumidLow)

                };
                db.SavedLoggers.InsertOnSubmit(addLogger);

                try
                {
                    db.SubmitChanges();
                    SetFormToOnLoad();
                    ReLoadLoggers();
                    _InsertNewRecord = false;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    MessageBox.Show(string.Format("An error occured while attempting to save the new record.\n{0}",ex),"Error adding record.");
                }
            }
        }
        private void UpdateLogger(DewkLogger Dewk)
        {
            if (Dewk.LastDownloadedThrough == null)
            {   // Database should also force default value of 1900-01-01 00:00:00.000
                Dewk.LastDownloadedThrough = new DateTime(1900, 01, 01, 00, 00, 00);
            }

            using (var db = new LMRDataContext())
            {

                var updateLogger =
                        (from logger in db.SavedLoggers
                         where logger.ID == this._RecordDatabaseKey
                         select logger).Single();

                //var addLogger =new SavedLogger(){

                updateLogger.LoggerName = Dewk.LoggerName;
                updateLogger.LoggerIpAddress = Dewk.IpAddress;
                updateLogger.LoggerDescription = Dewk.LoggerDescription;

                updateLogger.DisplayF = Dewk.DisplayF;
                updateLogger.LastDownloadedThrough = Dewk.LastDownloadedThrough;
                updateLogger.RecInterval = Dewk.RecordingInterval;

                updateLogger.Ch1Enabled = Dewk.Ch1Enabled;
                updateLogger.Ch2Enabled = Dewk.Ch2Enabled;

                updateLogger.Ch1TempHigh = System.Convert.ToDecimal(Dewk.Ch1TempHigh);
                updateLogger.Ch1TempLow = System.Convert.ToDecimal(Dewk.Ch1TempLow);
                updateLogger.Ch1HumidHigh = System.Convert.ToDecimal(Dewk.Ch1HumidHigh);
                updateLogger.Ch1HumidLow = System.Convert.ToDecimal(Dewk.Ch1HumidLow);

                updateLogger.Ch2TempHigh = System.Convert.ToDecimal(Dewk.Ch2TempHigh);
                updateLogger.Ch2TempLow = System.Convert.ToDecimal(Dewk.Ch2TempLow);
                updateLogger.Ch2HumidHigh = System.Convert.ToDecimal(Dewk.Ch2HumidHigh);
                updateLogger.Ch2HumidLow = System.Convert.ToDecimal(Dewk.Ch2HumidLow);

                //};
                //db.SavedLoggers.InsertOnSubmit(addLogger);

                try
                {
                    db.SubmitChanges();
                    SetFormToOnLoad();
                    ReLoadLoggers();
                    _InsertNewRecord = false;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    MessageBox.Show(string.Format("An error occured while attempting to save the new record.\n{0}", ex), "Error adding record.");
                }
            }
        }

        private void chkDailyDownload_CheckedChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.EnableDailyDownload = chkDailyDownload.Checked;
            Properties.Settings.Default.Save();
        }

        private void dtpDailyDownloadTime_ValueChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.DailyDownloadTime = dtpDailyDownloadTime.Value;
            Properties.Settings.Default.Save();
        }

        private void btnChangeDownloadFolder_Click(object sender, EventArgs e)
        {
            ChangeDownloadFolder();
        }

        private void ChangeDownloadFolder()
        {
            FolderBrowserDialog fbDialog = new FolderBrowserDialog();
            fbDialog.SelectedPath = "c:\\";
            DialogResult fbResult = fbDialog.ShowDialog();
            if (fbResult == DialogResult.OK)
            {
                Properties.Settings.Default.DownloadFolder = fbDialog.SelectedPath;
            }
            Properties.Settings.Default.Save();
            ReLoadDailyDownloadSettings();
        }
        private void ReLoadDailyDownloadSettings()
        {
            chkDailyDownload.Checked = Properties.Settings.Default.EnableDailyDownload;
            dtpDailyDownloadTime.Value = Properties.Settings.Default.DailyDownloadTime;
            lblDownloadFolder.Text = Properties.Settings.Default.DownloadFolder;
        }

        private void cboRecordingInterval_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void cboPacketSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.DownloadPacketSize = _PacketSizes[cboPacketSize.SelectedIndex];
            Properties.Settings.Default.Save();
        }

        private void SetTemperatureLabels()
        {
            if (chkDisplayF.Checked == true)
            {
                lblTemp1High.Text = "Temperature High (F)";
                lblTemp2High.Text = "Temperature High (F)";
                lblTemp1Low.Text = "Temperature Low (F)";
                lblTemp2Low.Text = "Temperature Low (F)";
            }
            if (chkDisplayF.Checked == false)
            {
                lblTemp1High.Text = "Temperature High (C)";
                lblTemp2High.Text = "Temperature High (C)";
                lblTemp1Low.Text = "Temperature Low (C)";
                lblTemp2Low.Text = "Temperature Low (C)";
            }
        }
        private void chkDisplayF_CheckedChanged(object sender, EventArgs e)
        {
            SetTemperatureLabels();
        }
    }
}
